﻿// -----------------------------------------------------------------------
// <copyright file="DiffieHellman.cs" company="Hewlett-Packard">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace SecutityLib
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public static class DiffieHellman
    {
        /// <summary>
        /// Gets the key at both sides.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <returns>Key using diffie Helman</returns>
        public static int[] GetKeyAtBothSides(string input)
        {
            int q, alpha, xa, xb;

            string[] tempValues = input.Split(',');
            if (tempValues.Length != 4)
            {
                throw new Exception("You have to enter the values in this format p,q,M,e seperated by commas");
            }

            try
            {
                q = int.Parse(tempValues[0]);
            }
            catch
            {
                throw new Exception("q must be an integer value");
            }

            try
            {
                alpha = int.Parse(tempValues[1]);
            }
            catch
            {
                throw new Exception("alpha must be an integer value");
            }

            try
            {
                xa = int.Parse(tempValues[2]);
            }
            catch
            {
                throw new Exception("Xa must be an integer value");
            }

            try
            {
                xb = int.Parse(tempValues[3]);
            }
            catch
            {
                throw new Exception("Xb must be an integer value");
            }

            int ya, yb;
            ya = GetValueOfMPowEmodN(alpha, xa, q);
            yb = GetValueOfMPowEmodN(alpha, xb, q);
            int[] result = new int[2];
            result[0] = GetValueOfMPowEmodN(yb, xa, q);
            result[1] = GetValueOfMPowEmodN(ya, xb, q);

            return result;
        }

        /// <summary>
        /// Gets the value of M pow emod N.
        /// </summary>
        /// <param name="m">The M.</param>
        /// <param name="e">The e.</param>
        /// <param name="n">The n.</param>
        /// <returns>the pow using composition</returns>
        private static int GetValueOfMPowEmodN(int m, int e, int n)
        {
            if (e == 1)
            {
                return m % n;
            }
            else if (e == 2)
            {
                return (int)Math.Pow(m, 2) % n;
            }
            else
            {
                int temp = GetValueOfMPowEmodN(m, e - 2, n) * GetValueOfMPowEmodN(m, 2, n);
                return temp % n;
            }
        }
    }
}
